package com.globalwave.system.service;

import com.globalwave.base.BaseServiceImpl;
import com.globalwave.common.ArrayOrderList;
import com.globalwave.common.ArrayPageList;
import com.globalwave.common.exception.BusinessException;
import com.globalwave.system.entity.Organization;
import com.globalwave.system.entity.OrganizationCriterion;
import com.globalwave.system.entity.OrganizationPrivilege;
import com.globalwave.system.entity.UserOrganization;

public class OrganizationServiceImpl extends BaseServiceImpl implements OrganizationService {

    public Organization create(Organization organization, Long[] privilege_ids) throws Exception {  

    	Long pid = organization.getPro_organization_id() ;
    	if (pid != null && lock(pid) == 0) {
    		throw new BusinessException("1051") ;//1051', '父组织不存在，本操作无效！
    	}
    	
        Organization newOrganization = (Organization) jdbcDao.insert(organization) ;
        
        if (privilege_ids != null) {
            for (Long privilege_id : privilege_ids) {
                OrganizationPrivilege orgPrivilege = new OrganizationPrivilege() ;
                orgPrivilege.setPrivilege_id(privilege_id) ;
                orgPrivilege.setOrganization_id(newOrganization.getOrganization_id()) ;
                jdbcDao.insert(orgPrivilege) ;
            }
        }
        
        return newOrganization;
    }
    public void update(Organization organization, Long[] privilege_ids) throws Exception {

    	lock(organization.getPro_organization_id()) ;
    	
        jdbcDao.update(organization) ;

        OrganizationPrivilege orgPrivilege = new OrganizationPrivilege() ;
        orgPrivilege.setOrganization_id(organization.getOrganization_id()) ;
        jdbcDao.delete(OrganizationPrivilege.class, orgPrivilege) ;
        
        if (privilege_ids != null) {
            for (Long privilege_id : privilege_ids) {
                orgPrivilege = new OrganizationPrivilege() ;
                orgPrivilege.setPrivilege_id(privilege_id) ;
                orgPrivilege.setOrganization_id(organization.getOrganization_id()) ;
                jdbcDao.insert(orgPrivilege) ;
            }
        }        
    }

    public void delete(Organization organization) throws Exception {

    	lock(organization.getPro_organization_id()) ;
    	
    	if (hasChildren(organization.getOrganization_id())) {
    		throw new BusinessException("1052") ;// 1052', '子组织存在，本操作无效！
    	}
        // delete cascade
        OrganizationPrivilege orgPrivilege = new OrganizationPrivilege() ;
        orgPrivilege.setOrganization_id(organization.getOrganization_id()) ;
        jdbcDao.delete(OrganizationPrivilege.class, orgPrivilege) ;
        
        // delete cascade
        UserOrganization userOrg = new UserOrganization() ;
        userOrg.setOrganization_id(organization.getOrganization_id()) ;
        jdbcDao.delete(UserOrganization.class,userOrg) ;
        
        jdbcDao.delete(organization) ;
        
    }

    public void deleteAll(Long[] organizationIds) throws Exception {
    	
    	for (Long oId:organizationIds) {
        	if (hasChildren(oId)) {
        		throw new BusinessException("1052") ;// 1052', '子组织存在，本操作无效！
        	}
    	}
    	
        OrganizationCriterion criterion = new OrganizationCriterion() ;
        criterion.setOrganizationIds(organizationIds) ;
        
        // delete cascade
        jdbcDao.delete(OrganizationPrivilege.class, criterion) ;
        jdbcDao.delete(UserOrganization.class, criterion) ;
        
        jdbcDao.delete(Organization.class, criterion) ;
        
    }
    
    private boolean hasChildren(Long organizationId) throws Exception {
    	Organization so = new Organization() ;
    	so.setPro_organization_id(organizationId) ;
    	return jdbcDao.getName("systemSQLs:organizationChildrenCount", so, 0L) > 0 ;
    }

    private int lock(Long organizationId) throws Exception {
    	if (organizationId == null) {
    		return 0;
    	}
    	
    	Organization o = new Organization() ;
    	o.setOrganization_id(organizationId) ;
    	o.addInclusions("organization_id") ;
    	
    	return jdbcDao.update(o) ;
    }
    public ArrayPageList<Organization> query(
            OrganizationCriterion organizationCriterion, 
            int pageIndex, 
            int pageSize, 
            ArrayOrderList orderList) 
    throws Exception {
        
        if (orderList == null) {
            orderList = new ArrayOrderList() ;
            orderList.addAsc("organization_id") ;
        }
        
        return (ArrayPageList<Organization>)jdbcDao.query(organizationCriterion, pageIndex, pageSize, orderList, Organization.class);
    }


    public ArrayPageList<Organization> userBelongTo(Long userId) throws Exception {
        
        String Sql = String.format(OrganizationCriterion.USER_BELONG_TO_ORGANIZATION, userId) ;
        return (ArrayPageList<Organization>)jdbcDao.query(new StringBuffer(Sql), null, 1, Integer.MAX_VALUE, null, Organization.class);
    }

}
